package cn.t.web.order;

import cn.t.constants.ResponseError;
import cn.t.core.exception.BizException;
import cn.t.core.mode.PageInfoDTO;
import cn.t.core.mode.PageQueryDTO;
import cn.t.core.mode.Result;
import cn.t.dto.order.CreateOrderRequest;
import cn.t.dto.order.DislodgeOrderDTO;
import cn.t.dto.order.ErrorDislodgeRequest;
import cn.t.dto.order.OrderQueryRequest;
import cn.t.dto.order.ToNormalRequest;
import cn.t.dto.order.UpdateOrderDTO;
import cn.t.dto.order.base.OrderSnRequest;
import cn.t.dto.order.base.VBaseDTO;
import cn.t.dto.order.excelresp.DislodgeExcelResp;
import cn.t.dto.order.excelresp.ErrorExcelResp;
import cn.t.enums.order.OrderTypeEnum;
import cn.t.facade.order.ExceptionLogFacade;
import cn.t.facade.order.OrderFacade;
import cn.t.listener.CustomCellWriteWidthConfig;
import cn.t.utils.ExcelUtil;
import cn.t.vo.order.DislodgeOrderDetailVO;
import com.alibaba.excel.EasyExcel;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * 领料订单服务入口
 *
 * @author l
 * @since 2024-05-24 10:15:14
 */
@Slf4j
@RestController
@RequestMapping("order")

@AllArgsConstructor
public class OrderController {
    @Resource
    private ExceptionLogFacade exceptionLogFacade;
    @Resource
    private OrderFacade orderFacade;

    /**
     * 领用列表查询接口
     */

    @PostMapping(value = "/getList")
    public PageInfoDTO<DislodgeOrderDTO> getList(@Validated @RequestBody PageQueryDTO<OrderQueryRequest> request) {
        return orderFacade.getOrderListPage(request, OrderTypeEnum.ORDER);
    }

    /**
     * 领用记录导出
     */

    @PostMapping("/getListExcel")
    public void getListExcel(@RequestBody OrderQueryRequest request,HttpServletResponse response) {
            List<DislodgeExcelResp> dislodgeExcelVO = orderFacade.openRecordExcel(request);
            if (ObjectUtils.isEmpty(dislodgeExcelVO)) {
                throw new BizException(ResponseError.EXCEL_EMPTY, ResponseError.EXCEL_EMPTY.getName());
            }
        try {
            ExcelUtil.setHeader(response,  URLEncoder.encode("领用列表", "UTF-8"));
        } catch (UnsupportedEncodingException e) {
            log.warn("领用列表导出异常 {}",e.getMessage());
            throw new BizException(ResponseError.EXCEL_EXPORT_ERR, ResponseError.EXCEL_EXPORT_ERR.getName());
        }
        // 执行导出
            try( ServletOutputStream outputStream = response.getOutputStream();) {

                EasyExcel.write(outputStream, DislodgeExcelResp.class).sheet("领用列表").registerWriteHandler(new CustomCellWriteWidthConfig()).doWrite(dislodgeExcelVO);
            } catch (Exception e) {
                log.warn("领用记录导出 {}",e.getMessage());
                throw new BizException(ResponseError.EXCEL_EXPORT_ERR, ResponseError.EXCEL_EXPORT_ERR.getName());
            }

    }


    /**
     * 领用商品详情查询接口
     */

    @PostMapping(value = "/getDislodgeLine")
    public VBaseDTO<DislodgeOrderDTO, DislodgeOrderDetailVO> getDislodgeLine(@Validated @RequestBody OrderSnRequest orderSn) {
        return orderFacade.getDislodgeInfo(orderSn, OrderTypeEnum.ORDER);
    }

    /**
     * 创建领用记录
     */

    @PostMapping(value = "/create")
    public Result createOrder(@Validated @RequestBody CreateOrderRequest request) {
        return Result.success(orderFacade.createOrder(request));
    }


    /**
     * 删除领用记录
     */

    @PostMapping(value = "/delete/{orderSn}")
    public void deleteByOrderSn(@Validated @PathVariable("orderSn") String orderSn) {
        if (ObjectUtils.isEmpty(orderSn)) {
            throw new BizException(ResponseError.PARAM_NOT_FOUND, ResponseError.PARAM_NOT_FOUND.getName());
        }
        orderFacade.deleteOrder(orderSn);
    }
    /**
     * 编辑领用明细
     */

    @PostMapping(value = "/updateOrderGoods")
    public void updateOrderGoods(@Validated @RequestBody UpdateOrderDTO request) {
          orderFacade.updateOrderGoods(request);
    }


    /**
     * 异常领用列表查询接口
     */
    @PostMapping(value = "/getErrorList")
    public PageInfoDTO<DislodgeOrderDTO> getErrorList(@Validated @RequestBody PageQueryDTO<OrderQueryRequest> request) {
        return exceptionLogFacade.getErrorList(request);
    }

    /**
     * 异常类型查询接口导出
     */
    @PostMapping ("/errListExcel")
    public void exportErrListExcel(HttpServletResponse response, @RequestBody ErrorDislodgeRequest req) {
        List<ErrorExcelResp> errorExcelRespList = exceptionLogFacade.openRecordExcel(req);
        if (ObjectUtils.isEmpty(errorExcelRespList)) {
            throw new BizException(ResponseError.EXCEL_EMPTY, ResponseError.EXCEL_EMPTY.getName());
        }

        try {
            ExcelUtil.setHeader(response,  URLEncoder.encode("异常领用列表", "UTF-8"));
        } catch (UnsupportedEncodingException e) {
            log.warn("异常领用列表导出异常 {}",e.getMessage());
            throw new BizException(ResponseError.EXCEL_EXPORT_ERR, ResponseError.EXCEL_EXPORT_ERR.getName());
        }
        // 执行导出
        try( ServletOutputStream outputStream = response.getOutputStream();) {

            EasyExcel.write(outputStream, ErrorExcelResp.class).sheet("领用列表").registerWriteHandler(new CustomCellWriteWidthConfig()).doWrite(errorExcelRespList);
        } catch (Exception e) {
            log.warn("导出异常 {}",e.getMessage());
            throw new BizException(ResponseError.EXCEL_EXPORT_ERR, ResponseError.EXCEL_EXPORT_ERR.getName());
        }

    }

    /**
     * 异常领用详情查询接口
     */

    @PostMapping(value = "/getErrorDislodgeLine")
    public VBaseDTO<DislodgeOrderDTO, DislodgeOrderDetailVO> getExceptionOrderDetail(@Validated @RequestBody OrderSnRequest orderSn) {
        VBaseDTO<DislodgeOrderDTO, DislodgeOrderDetailVO> dislodgeErrInfo = exceptionLogFacade.getDislodgeErrInfo(orderSn);
        VBaseDTO<DislodgeOrderDTO, DislodgeOrderDetailVO> dislodgeInfo = orderFacade.getDislodgeInfo(orderSn, OrderTypeEnum.ERRORDER_TYPE);
        List<DislodgeOrderDetailVO> detail1 = dislodgeInfo.getDetail();
        if (ObjectUtils.isNotEmpty(detail1)){
            List<DislodgeOrderDetailVO> detail = dislodgeErrInfo.getDetail();
            dislodgeErrInfo.setDetail(Stream.concat(detail.stream(), detail1.stream()).collect(Collectors.toList()));
        }
        return dislodgeErrInfo;
    }

    /**
     * 异常转正常订单接口
     */
    @PostMapping(value = "/toNormalOrder")
    public void errorToNormal(@Validated @RequestBody ToNormalRequest request) {
        exceptionLogFacade.toErrorToNormal(request);
    }

    /**
     * 异常转已处理订单接口
     */
    @PostMapping(value = "/toProcessed")
    public void errorToProcessed(@Validated @RequestBody OrderSnRequest request) {
        exceptionLogFacade.errorOrderToProcessed(request);
    }

    /**
     * 疑似未领取列表查询接口
     */
    @PostMapping(value = "/getUnclaimedList", produces = "application/json;charset=UTF-8")
    public PageInfoDTO<DislodgeOrderDTO> getUnclaimedList(@Validated @RequestBody PageQueryDTO<OrderQueryRequest> request) {
        return orderFacade.getUnclaimedList(request, OrderTypeEnum.UN_ORDER);
    }

    /**
     * 转单记录列表查询接口
     */
    @PostMapping(value = "/getTransferList", produces = "application/json;charset=UTF-8")
    public PageInfoDTO<DislodgeOrderDTO> getTransferList(@Validated @RequestBody PageQueryDTO<OrderQueryRequest> request) {
        return orderFacade.getOrderListPage(request, OrderTypeEnum.TRANSFER_ORDER);
    }

    /**
     * 转单商品详情接口
     */
    @PostMapping(value = "/getTransferGoodsLine", produces = "application/json;charset=UTF-8")
    public VBaseDTO<DislodgeOrderDTO, DislodgeOrderDetailVO> getTransferGoodsLine(@Validated @RequestBody OrderSnRequest request) {
        return exceptionLogFacade.getDislodgeErrInfo(request);
    }
}

